﻿// Decompiled with JetBrains decompiler
// Type: Netick.InterestManagementGroup
// Assembly: Netick, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 6726ECA1-C773-4CF7-8952-E81B30D93B52
// Assembly location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.dll
// XML documentation location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.xml

using System.Collections.Generic;
using System.Numerics;

#nullable disable
namespace Netick;

/// <summary>
/// Represents a group used for interest management in the Netick.
/// An InterestManagementGroup contains a collection of entities and manages which clients are interested in those entities,
/// typically for the purpose of optimizing network traffic by only sending relevant updates to clients.
/// </summary>
public sealed class InterestManagementGroup
{
  public object UserObject;
  internal InterestManagement IM;
  internal NetickEngine Engine;
  internal Entity Entity;
  internal int Index = -1;
  public readonly Vector3 Position;
  public readonly NetickVector3Int GridPosition;
  internal bool[] Clients;
  internal HashSet<Entity> _entities;
  private NativeIdStack _idStack;
  internal NativeArray<int> _idToWorldIndex;

  public IReadOnlyCollection<Entity> Entities => (IReadOnlyCollection<Entity>) this._entities;

  internal InterestManagementGroup(
    InterestManagement im,
    int index,
    int initialCapacity,
    Vector3 pos,
    NetickVector3Int gridPosition)
  {
    this.Engine = im.Engine;
    this.IM = im;
    this.Index = index;
    this.GridPosition = gridPosition;
    this.Position = pos;
    this._entities = new HashSet<Entity>(100);
    if (!this.Engine.IsServer)
      return;
    this.Clients = new bool[this.Engine.MaxClients];
    this._idStack.Allocate((IAllocator) im._allocator, initialCapacity);
    this._idToWorldIndex.Allocate((IAllocator) im._allocator, initialCapacity);
    this._idStack.InitIds();
    this.Entity = new Entity(this.Engine, (INetickEntity) null, (ISafeAllocator) im._allocator, (IAllocator) im._allocator, (long) initialCapacity, true, false, true, true);
    this.Entity.RawId = 900000;
  }

  internal void AddEntity(Entity memberEntity)
  {
    this._entities.Add(memberEntity);
    if (this.Engine.IsClient)
      return;
    if (this._idStack.Count == 0)
    {
      this._idStack.ExpandCapacityAndInitNewIds((IAllocator) this.IM._allocator);
      this._idToWorldIndex.ExpandCapacity((IAllocator) this.IM._allocator);
      this.Entity.ExpandMetaForAoiEntity((IAllocator) this.IM._allocator);
    }
    int num = this._idStack.Pop();
    this._idToWorldIndex[num] = memberEntity.WorldIndex;
    memberEntity.GroupTableId = num;
    this.Engine._entityMetaReplicator.SetInterestGroup(memberEntity, this.Index);
    this.Entity.InterestMarkAltered(num);
    memberEntity.ResetSnapshotTicks();
  }

  internal void RemoveEntity(Entity memberEntity, int groupTableIndex, bool removeFromList = true)
  {
    if (removeFromList)
      this._entities.Remove(memberEntity);
    if (this.Engine.IsClient || memberEntity.RawId == -1)
      return;
    this.Entity.TRC(groupTableIndex);
    this._idStack.Push(groupTableIndex);
    this._idToWorldIndex[groupTableIndex] = -1;
  }
}
